package com.irs.irsforum.utils;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

import static java.util.Calendar.DAY_OF_MONTH;
/**
 * @author Liyihui
 * @Date: 2020/3/22
 * @Time: 3:09
 */
public class TimeUtil {

    public static final int MINUTE_IN_SECONDS = 60;

    public static final int FIVE_MINUTE_IN_SECONDS = 300;

    public static final int HOUR_IN_SECONDS = MINUTE_IN_SECONDS * 60;

    public static final int DAY_IN_SECONDS = HOUR_IN_SECONDS * 24;

    public static final int WEEK_IN_SECONDS = DAY_IN_SECONDS * 7;


    public static final long SECOND_IN_MILLISECONDS = 1000L;

    public static final long MINUTE_IN_MILLISECONDS = MINUTE_IN_SECONDS * SECOND_IN_MILLISECONDS;

    public static final long HOUR_IN_MILLISECONDS = HOUR_IN_SECONDS * SECOND_IN_MILLISECONDS;

    public static final long DAY_IN_MILLISECONDS = DAY_IN_SECONDS * SECOND_IN_MILLISECONDS;

    public static final long WEEK_IN_MILLISECONDS = DAY_IN_SECONDS * SECOND_IN_MILLISECONDS;


    public static final String HOUR_IN_CHINESE = "时";

    public static final String MINUTE_IN_CHINESE = "分";

    public static final String SECOND_IN_CHINESE = "秒";

    public static DateTimeFormatter dateSlashFormat = DateTimeFormat.forPattern(
            "MM/dd/yyyy");

    public static DateTimeFormatter dateDotFormat = DateTimeFormat.forPattern(
            "yyyy.MM.dd");

    public static DateTimeFormatter dateFullFormat = DateTimeFormat.forPattern(
            "yyyy-MM-dd");

    public static DateTimeFormatter dateTimeFullFormat = DateTimeFormat.forPattern(
            "yyyy-MM-dd HH:mm:ss");

    public static DateTimeFormatter dateTimeNumFormat = DateTimeFormat.forPattern(
            "yyyyMMddHHmmss");

    public static DateTimeFormatter dateTimeMillNumFormat = DateTimeFormat.forPattern(
            "yyyyMMddHHmmssSSS");

    // get string like 01/01/2018
    public static String millsToDateSlashStr(long mills) {
        return dateSlashFormat.print(mills);
    }

    // get string like 2018.01.01
    public static String millsToDateDotStr(long mills) {
        return dateDotFormat.print(mills);
    }

    // get string like 2018-01-01
    public static String millsToDateFullStr(long mills) {
        return dateFullFormat.print(mills);
    }

    // get string like 2018-01-01 00:00:00
    public static String millsToDateTimeFullStr(long mills) {
        return dateTimeFullFormat.print(mills);
    }

    // get string like 20171225091010
    public static String millsToDateTimeNumStr(long mills) {
        return dateTimeNumFormat.print(mills);
    }

    // get string like 20171225091010175, millisecond
    public static String millsToDateTimeMillNumStr(long mills) {
        return dateTimeMillNumFormat.print(mills);
    }

    // trans string like 2018-01-01 00:00:00 to long
    public static long dateTimeFullStrToLong(String timeStr) {
        DateTime time = dateTimeFullFormat.parseDateTime(timeStr);
        return time.getMillis();
    }

    // trans string like 20171225091010 to long
    public static long dateTimeNumStrToLong(String timeStr) {
        DateTime time = dateTimeNumFormat.parseDateTime(timeStr);
        return time.getMillis();
    }

    public static String dateToWeekDay(Date time) {
        SimpleDateFormat dateFm = new SimpleDateFormat("EEE", Locale.US);
        return dateFm.format(time);
    }

    /**
     * On the same hour, compute time interval between current to end. For
     * example: present is 10:30, end will be 10:40 The time interval will be 10
     * * 60 * 1000 milliseconds.
     *
     * @param endMin end time
     * @return time interval (show as milliseconds, accurate to minute)
     */
    public static long computeTimeInterval(int endMin) {
        GregorianCalendar currCalendar = new GregorianCalendar();
        GregorianCalendar endCalendar = new GregorianCalendar(
                currCalendar.get(Calendar.YEAR),
                currCalendar.get(Calendar.MONTH),
                currCalendar.get(DAY_OF_MONTH),
                currCalendar.get(Calendar.HOUR_OF_DAY), endMin,
                currCalendar.get(Calendar.SECOND));
        Date currDate = currCalendar.getTime();
        Date endDate = endCalendar.getTime();
        // divide MIN_TO_MILLISECONDS and multiply MIN_TO_MILLISECONDS again
        // try to avoid executing the task at the last second in minute.
        return (endDate.getTime() - currDate.getTime()) / MINUTE_IN_MILLISECONDS
                * MINUTE_IN_MILLISECONDS;
    }

    /**
     * In the same day, compute time interval between current to end. For
     * example: present is 10:30, end will be 11:40 The time interval will be 70
     * * 60 * 1000 milliseconds.
     *
     * @param endHour end hour
     * @param endMin  end minute
     * @return time interval (show as milliseconds, accurate to minute)
     */
    public static long computeTimeInterval(int endHour, int endMin) {
        GregorianCalendar currCalendar = new GregorianCalendar();
        GregorianCalendar endCalendar = new GregorianCalendar(
                currCalendar.get(Calendar.YEAR),
                currCalendar.get(Calendar.MONTH),
                currCalendar.get(DAY_OF_MONTH), endHour, endMin,
                currCalendar.get(Calendar.SECOND));
        Date currDate = currCalendar.getTime();
        Date endDate = endCalendar.getTime();
        return (endDate.getTime() - currDate.getTime()) / MINUTE_IN_MILLISECONDS
                * MINUTE_IN_MILLISECONDS;
    }


    public static Date getDate(Date date, int intervalDay) {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);
        gc.add(DAY_OF_MONTH, intervalDay);
        return gc.getTime();
    }

    //获取当天的开始时间
    public static Date getDayBegin() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    // 获取输入日期当天的开始时间
    public static Date getDayBegin(Date today) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(today);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    // 获取输入日期下一天的开始时间
    public static Date getNextDayBegin(Date today) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(today);
        cal.add(Calendar.DATE, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    // 获取输入日期前一天的开始时间
    public static Date getPreviousDayBegin(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, -1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    //获取当天的结束时间
    public static Date getDayEnd() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime();
    }

    // 获取输入日期当天的结束时间
    public static Date getDayEnd(Date today) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(today);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime();
    }

    /**
     * 把秒转化为几时几分几秒的字符串表示
     *
     * @param seconds
     * @return
     */
    public static String secondsToHourString(long seconds) {

        if (seconds <= 0) {
            return String.valueOf(seconds);
        }

        StringBuilder sb = new StringBuilder();
        long hours = seconds / HOUR_IN_SECONDS;
        if (hours > 0) {
            sb.append(hours).append(HOUR_IN_CHINESE);
        }
        seconds = seconds % HOUR_IN_SECONDS;
        long minutes = seconds / MINUTE_IN_SECONDS;
        if (minutes > 0) {
            sb.append(minutes).append(MINUTE_IN_CHINESE);
        }
        seconds = seconds % MINUTE_IN_SECONDS;
        if (seconds > 0) {
            sb.append(seconds).append(SECOND_IN_CHINESE);
        }
        return sb.toString();
    }


    /**
     * 当前季度的开始时间
     */
    public static Date getCurrentQuarterStartTime() {
        Calendar c = new GregorianCalendar();
        int currentMonth = c.get(Calendar.MONTH) + 1;

        if (currentMonth >= 1 && currentMonth <= 3) {
            c.set(Calendar.MONTH, 0);
        } else if (currentMonth >= 4 && currentMonth <= 6) {
            c.set(Calendar.MONTH, 3);
        } else if (currentMonth >= 7 && currentMonth <= 9) {
            c.set(Calendar.MONTH, 6);
        } else if (currentMonth >= 10 && currentMonth <= 12) {
            c.set(Calendar.MONTH, 9);
        }
        c.set(Calendar.DATE, 1);

        String dateStr = dateFullFormat.print(c.getTimeInMillis()) + " 00:00:00";

        return dateTimeFullFormat.parseDateTime(dateStr).toDate();
    }

    public static Date getAfterCurrentTime(String today, Integer day) throws ParseException {
        DateTime dateTime = dateFullFormat.parseDateTime(today);
        Calendar cal = Calendar.getInstance();
        cal.setTime(dateTime.toDate());
        cal.add(Calendar.DATE, day);
        String print = dateTimeFullFormat.print(cal.getTimeInMillis());
        System.out.println(print);
        return cal.getTime();
    }


    //格式："2018-05-28T08:54:47.551+08:00"
    private static ThreadLocal<SimpleDateFormat> simpleDateFormat =
            new ThreadLocal<SimpleDateFormat>() {
                @Override
                protected SimpleDateFormat initialValue() {
                    return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
                }
            };

    public static String unixToLocalTime(long time) {
        String strDate = time + "";
        String date = simpleDateFormat.get().format(new java.util.Date(Long.parseLong(strDate)));
        return date + "+08:00";
    }

    public static Date getStringToDate(String dateString) throws ParseException {
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = sdf.parse(dateString);

        return date;
    }

    public static Timestamp getSqlTime() {
        return new Timestamp(new java.util.Date().getTime());
    }

    public static Long getDayMillisecond(Integer day){
        long milliSencond = day * (24 * 3600 * 1000L);
        return milliSencond;
    }

    public static Long getHourMillisecond(Integer hour){
        long milliSencond = hour * (3600 * 1000L);
        return milliSencond;
    }

    public static Long getMinuteMillisecond(Long min){
        long milliSencond = min * (60 * 1000L);
        return milliSencond;
    }
    /**
     * 得到两个时间的时间差
     *
     * @param date1
     * @param date2
     * @return
     */
    public static Long compareDate(Date date1, Date date2) {
        return Math.abs(date1.getTime() - date2.getTime());
    }

    public static void main(String[] args) throws ParseException {
//        String date1 = "2020-12-13 22:12:23";
//        String date2 = "2020-12-13 20:21:23";
//
//        Date stringToDate = getStringToDate(date1);
//        Date stringToDate1 = getStringToDate(date2);
//
//        Long aLong = compareDate(stringToDate1, stringToDate);
//
//        Long hourMillisecond = getHourMillisecond(1);
//        if(aLong <= hourMillisecond)
//            System.out.println(true);
//        else
//            System.out.println(false);

        Date afterCurrentTime = getAfterCurrentTime("aa", 30);
    }
}
